﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using MyTask.Application.Services;
using MyTask.Domain.Commands.Handlers;
using MyTask.Domain.Queries.Handlers;
using MyTask.Infrastructure.Context;
using MyTask.WebApi.Filters;

namespace MyTask.WebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Service
            //Injection service
            services.AddScoped<IUserInfoService, UserInfoService>();
            services.AddScoped<ITaskInfoService, TaskInfoService>();
            services.AddScoped<UserInfoCommandHandler>();
            services.AddScoped<ShareTaskCommandHandler>();
            services.AddScoped<TaskInfoCommandHandler>();
            services.AddScoped<TaskInfoQueryHandler>();
            services.AddScoped<UserInfoQueryHandler>();
            #endregion
            #region Cross domain
            //Cross domain
            services.AddCors(options =>
            {
                options.AddPolicy("AnyOrigin", builder =>
                {
                    builder
                       .WithOrigins("http://localhost:3000", "http://127.0.0.1")
                       .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
            }); 
            #endregion
            services.AddMvc(o=> {
                o.Filters.Add(typeof(LogAttribute));
                o.Filters.Add(typeof(GlobalExceptionFilter));
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            #region Sqlserver
            //Sqlserver
            services.AddDbContext<MyTaskContext>(optionsAction: optionsBuilder =>
            optionsBuilder.UseSqlServer(Configuration["ConnectionString"],
            optionsAction => optionsAction.MigrationsAssembly(typeof(MyTaskContext).GetTypeInfo().Assembly.GetName().Name))); 
            #endregion
            #region Jwt
            // jwt validation
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,//是否验证Issuer
                        ValidateAudience = true,//是否验证Audience
                        ValidateLifetime = true,//是否验证失效时间
                        ClockSkew = TimeSpan.Zero,//校验时间是否过期时，设置的时钟偏移量,
                        ValidateIssuerSigningKey = true,//是否验证SecurityKey
                        ValidAudience = Configuration.GetSection("JwtSetting:Audience").Value,//Audience
                        ValidIssuer = Configuration.GetSection("JwtSetting:Issuer").Value,//Issuer，这两项和前面签发jwt的设置一致
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("JwtSetting:SecurityKey").Value))//拿到SecurityKey
                    };
                }); 
            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseCors("AnyOrigin");
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}
